package org.jtrace.geometry;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.jtrace.BoundingBox;
import org.jtrace.Material;
import org.jtrace.Scene;
import org.jtrace.io.PlyReader;
import org.jtrace.primitives.Point3D;

public class MeshObject {
	
	private Point3D max;
	private Point3D min;
	private Point3D center;
	private List<Triangle> triangles;
	private BoundingBox boundingBox;

	public MeshObject(String plyFile, Material material) throws IOException {
		InputStream inputStream = new FileInputStream(plyFile);
		this.triangles = PlyReader.read(inputStream, material);
		initMesh();
		System.out.println("Centro: " + getCenter());
	}

	public void initMesh() {
		this.max = new Point3D(Double.MIN_VALUE, Double.MIN_VALUE, Double.MIN_VALUE);
		this.min = new Point3D(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE);
		
		for (Triangle t : triangles) {
			t.setMesh(this);
			
			Point3D[] array = new Point3D[]{ t.getV1(), t.getV2(), t.getV3() };
			
			for (int i = 0; i < array.length; i++) {
				Point3D p = array[i];
				if (p.getX() > this.max.getX()) this.max.setX(p.getX());
				if (p.getY() > this.max.getY()) this.max.setY(p.getY());
				if (p.getZ() > this.max.getZ()) this.max.setZ(p.getZ());
				if (p.getX() < this.min.getX()) this.min.setX(p.getX());
				if (p.getY() < this.min.getY()) this.min.setY(p.getY());
				if (p.getZ() < this.min.getZ()) this.min.setZ(p.getZ());
			}
		}
		
		//calculando centro
		double x = (this.max.getX() - this.min.getX()) / 2 + this.min.getX();
		double y = (this.max.getY() - this.min.getY()) / 2 + this.min.getY();
		double z = (this.max.getZ() - this.min.getZ()) / 2 + this.min.getZ();
		this.center = new Point3D(x, y, z);
		
		//calculando boudingbox
		boundingBox = new BoundingBox(this.triangles, this.max, this.min);
	}
	
	public void insertScene(Scene scene){
		for (Triangle t : triangles) 
			scene.add(t);
	}
	
	public BoundingBox getBoundingBox() {
		return boundingBox;
	}
	
	public Point3D getMax() {
		return max;
	}

	public Point3D getMin() {
		return min;
	}

	public Point3D getCenter() {
		return center;
	}

	public List<Triangle> getTriangles() {
		return triangles;
	}

}